<html>
    <head>
        <title>列表过渡</title>
    </head>
    <body>
        <script>
            // 列表过渡
                     /*
                         目前为止，关于过渡我们已经讲到：
                            1、单节点
                            2、同一个时间渲染多个节点中的一个
                        
                         那么怎么同时渲染整个列表,比如使用v-for？ 在这种场景中，使用 <transition-group> 组件.
                         在我们深入例子之前，先了解关于这个组件的几个特点：
                            1、不同于 <transition>， 它会以一个真实元素呈现：  
                                        默认为一个<span>,你也可以通过 tag 标签属性更换为其他元素。
                            2、"过渡模式"不可用,因为我们不再相互切换特有元素。
                            3、内部元素"总是需要"提供唯一的 key 标签属性
                            4、CSS过渡的类将会应用在内部的元素中，而不是这个组件/容器本身。
                    */


                    // 一、列表的进入/离开过渡
                               /*
                                     现在让我们由一个简单的例子深入，进入和离开的过渡使用之前一样的CSS类名。
                                     

                                            <div id="list-demo" class="demo">
                                                <button v-on:click="add">Add</button>
                                                <button v-on:click="remove">Remove</button>
                                                <transition-group name="list" tag="p">
                                                    <span v-for="item in items" v-bind:key="item" class="list-item">
                                                        {{ item}}
                                                    </span>
                                                </transition-group>
                                            </div>
                               */

                                            new Vue({
                                                el:'#list-demo',
                                                data:{
                                                    items:[1,2,3,4,5,6,7,8,9],
                                                    nextNum:10
                                                },
                                                methods: {
                                                    randomIndex:function(){
                                                        return Math.floor(Math.random()*this.items.length)
                                                    },
                                                    add:function(){
                                                        this.items.splice(this.randomIndex(),0,this.nextNum++)
                                                    },
                                                    remove:function(){
                                                        this.items.splice(this.randomIndex(),1)
                                                    }
                                                },
                                            });

                                /*
                                    .list-item{
                                        display:inline-block;
                                        margin-right:10px;
                                    }

                                    .list-enter-action .list-leave-active{
                                        transition:all 1s;
                                    }

                                    .list-enter, .list-leave-to{
                                        opacity:0;
                                        transform:translateY(30px);
                                    }
                                */
                                
                                /*
                                    这个例子有个问题，当添加和移除元素的时候，周围的元素会瞬间移动到他们的新布局的位置，而不是平滑的过渡。
                                    我们下面会解决这个问题。
                                */


                    // 二、列表的排序过渡
                                /*
                                    <transition-group>组件还有一个特殊之处。
                                    不仅可以有 "进入" 和 "离开" 动画，还可以改变定位。
                                    要使用这个新功能只需要了解新增的 v-move class,它会在元素的改变定位的过程中应用。 
                                    像之前的类名一样，可以通过 name 标签属性来自定义前缀，也可以通过 move-class 标签属性手动设置。

                                    v-move 对于设施过渡的奇幻时机和多度曲线非常有用，你会看到如下的例子：

                                        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"><-/script>
                                        <div id="flip-list-demo">
                                            <transistion-group name="flip-list" tag="ul">
                                                <li v-for="item in items" v-bind:key="item">
                                                    {{ item}}
                                                </li>
                                            </transistion-group>
                                        </div>
                                */

                                        new Vue({
                                            el:'#flip-list-demo',
                                            data:{
                                                items:[1,2,3,4,5,6,7,8,9]
                                            },
                                            methods:{
                                                shuffle:function(){
                                                    this.items=_.shuffle(this.items)
                                                }
                                            }
                                        })
                                /*
                                    .flip-lsit-move{
                                        transition: transform 1s;
                                    }
                                */



                                /*
                                    这个看起来很神奇，内部的实现，Vue使用了一个叫"Flip"的"简单动画队列"，使用 transforms 将元素从之前的位置平滑过渡到新的位置。

                                    我们将之前实现的例子和这个技术结合，使我们列表的一切变动都会有动画过渡：


                                        <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"><-/script>
                                        <div id="list-complete-demo" class="demo">
                                            <button v-on:click="shuffle">Shuffle</button>
                                            <button v-on:click="add">Add</button>
                                            <button v-on:click="remove">Remove</button>
                                            <transition-group name="list-complete" tag="p">
                                                <span 
                                                    v-for="item in items"
                                                    v-bind:key="item"
                                                    classs="list-complete-item"
                                                >
                                                    {{ item }}
                                                </span>
                                            </transition-group>
                                        </div>
                                */
                                        new Vue({
                                            el:'#list-complete-demo',
                                            data:{
                                                items:[1,2,3,4,5,6,7,8,9],
                                                nextNum:10
                                            },
                                            methods:{
                                                randomIndex:function(){
                                                    return Math.floor(Math.random()*this.itemsl.length)
                                                },
                                                add:function(){
                                                    this.items.splice(this.randomIndex(),0,this.nextNum++)
                                                },
                                                remove:function(){
                                                    this.items.splice(this.randomIndex(),1)
                                                },
                                                shuffle:function(){
                                                    this.items =_.shuffle(this.items)
                                                }
                                            }
                                        })
                                /*
                                    .list-complete-item {
                                        transition: all 1s;
                                        display: inline-block;
                                        margin-right: 10px;
                                    }
                                    .list-complete-enter, .list-complete-leave-to{
                                        opacity: 0;
                                        transform: translateY(30px);
                                    }
                                    .list-complete-leave-active {
                                        position: absolute;
                                    }
                                */


                    
                    // 三、列表的交错过渡
                                // 通过 data attribute(标签属性) 与 JavaScript 通信，就可以实现列表的交错过渡：

                                /*
                                        velocity.js 是一个动画库，它比原生 CSS 过渡和动画提供了更多的功能和更好的性能。

                                        <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"><-/script>

                                        <div id="staggered-fade">
                                            <input v-model="query">
                                            <transition-group
                                                name="staggered-fade"
                                                tag="p"
                                                v-bind:css="false"
                                                v-on:before-enter="beforeEnter"
                                                v-on:enter="enter"
                                                v-on:leave="leave"
                                            >
                                                <li v-for="(item,index) in computedList"
                                                    v-bind:key="item.msg"
                                                    v-bind:data-index="index"
                                                >
                                                    {{ item.msg}}
                                                </li>
                                            </transtition-group>
                                        </div>
                                */
                                
                                new Vue({
                                    el: '#staggered-list-demo',
                                    data: {
                                        query: '',
                                        list: [
                                        { msg: 'Bruce Lee' },
                                        { msg: 'Jackie Chan' },
                                        { msg: 'Chuck Norris' },
                                        { msg: 'Jet Li' },
                                        { msg: 'Kung Fury' }
                                        ]
                                    },
                                    computed: {
                                        computedList: function () {
                                        var vm = this
                                        return this.list.filter(function (item) {
                                            return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
                                        })
                                        }
                                    },
                                    methods: {
                                        beforeEnter: function (el) {
                                        el.style.opacity = 0
                                        el.style.height = 0
                                        },
                                        enter: function (el, done) {
                                        var delay = el.dataset.index * 150
                                        setTimeout(function () {
                                            Velocity(
                                            el,
                                            { opacity: 1, height: '1.6em' },
                                            { complete: done }
                                            )
                                        }, delay)
                                        },
                                        leave: function (el, done) {
                                        var delay = el.dataset.index * 150
                                        setTimeout(function () {
                                            Velocity(
                                            el,
                                            { opacity: 0, height: 0 },
                                            { complete: done }
                                            )
                                        }, delay)
                                        }
                                    }
                                })

                                

                                

        </script>
    </body>
</html>xc    